Jak odstranit poslední sloupec souboru v systému Linux

Chci smazat poslední sloupec souboru txt, i když nevím, jaké číslo sloupce je. Jak to mohu udělat?

Příklad:

Vstup:

1223 1234 1323 ... 2222 123 1233 1234 1233 ... 3444 125 0000 5553 3455 ... 2334 222 

A chci, aby byl můj výstup :

1223 1234 1323 ... 2222 1233 1234 1233 ... 3444 0000 5553 3455 ... 2334 

Komentáře

  • Existuje mnoho způsobů, jak toho dosáhnout..přidejte příklad a váš očekávaný výstup z toho ..
  • @heemayl dobře, udělal jsem
  • díky..jsou oddělené karty sloupců nebo oddělené mezerami?
  • @heemayl mezera
  • cut zní jako nástroj pro danou úlohu.

Odpovědět

S awk:

awk "NF{NF-=1};1" <in >out 

nebo:

awk "NF{NF--};1" <in >out 

nebo:

awk "NF{--NF};1" <in >out 

Ačkoli to vypadá jako vúdú, funguje to. Každý z těchto příkazů awk má tři části.

První je NF, což je předpoklad pro druhou část. NF je proměnná obsahující počet polí v řádku. V AWK jsou věci pravdivé, pokud „nejsou 0 nebo prázdný řetězec "". Druhá část (tedy NF je snížena) nastane, pouze pokud NF není 0.

Druhá část (buď NF-=1 nebo --NF) právě odečítá jeden z proměnné NF. Tím se zabrání vytištění posledního pole, protože když změníte pole (v tomto případě odstraníte poslední pole), awk znovu sestavit $0, ve výchozím nastavení zřetězit všechna pole oddělená mezerou . $0 již neobsahuje poslední pole.

Poslední část je 1. Není to kouzelné, používá se pouze jako výraz, který znamená true. Pokud je výraz awk vyhodnocen jako true bez jakékoli přidružené akce, awk výchozí akce je print $0 .

Komentáře

  • @JJoao: Ach, díky, zapomněl jsem na --. Poznámka, aktuálně potřebujete ;1 vyhovující POSIX.
  • Mým původním instinktem by bylo použít smyčku for, ale je to mnohem výstižnější a chytřejší.
  • ' Stojí za zmínku, že pokud ' používáte jiný než výchozí oddělovač, ' Budu muset provést nějaké změny. Za předpokladu, že , je váš oddělovač: awk -F',' 'BEGIN { OFS = FS }; NF { NF -= 1 }; 1' < in > out
  • Účinkem snižování NF je nedefinované chování POSIX – získáte odlišný výstup podle toho, které awk ' znovu spouštíte. Některá awks odstraní poslední pole, jak chcete, některá neudělají vůbec nic a další mohou nahlásit syntaktickou chybu nebo něco jiného.

Odpovědět

Používání grep s PCRE:

$ grep -Po ".*(?=\s+[^\s]+$)" file.txt 1223 1234 1323 ... 2222 1233 1234 1233 ... 3444 0000 5553 3455 ... 2334 

Používání GNU sed:

$ sed -r "s/(.*)\s+[^\s]+$/\1/" file.txt 1223 1234 1323 ... 2222 1233 1234 1233 ... 3444 0000 5553 3455 ... 2334 

Komentáře

  • @ramin Jistě. .mohl byste se na to zeptat jako nová otázka (takhle funguje tento web) 🙂
  • @ramin Dává vám nějaké časové omezení nebo jakékoli varování?
  • říká, že to není standardní otázka!
  • @ramin ok .. dovolte mi kontaktovat administrátora, může vám s tím pomoci .. btw zkontroloval jste nějaké staré QA týkající se vaší otázky? je možné, že otázka je již položena a zodpovězena.
  • Nepokládejte ' superzákladní otázky jako " jak mohu v Linuxu přejmenovat název souboru ". Používejte Google.

Odpověď

Používání Perlu:

perl -lane "$,=" ";pop(@F);print(@F)" in 

Použití rev + cut:

rev in | cut -d " " -f 2- | rev 

Odpověď

Používání GNU sed:

sed -r "s/\s+\S+$//" input.txt 

Obecněji, tento pracuje s BSD sed v OSX, stejně jako GNU sed:

sed "s/[[:space:]]\{1,\}[^[:space:]]\{1,\}$//" input.txt 

Answer

Pokud je oddělovač vždy jeden znak (takže dva nebo více po sobě jdoucích oddělovačů označuje prázdná pole), můžete head použít pouze první řádek ze vstupního souboru, spočítat oddělovače ( n oddělovače znamená, že počet polí je n+1) a poté použijte cut k tisku z 1 první pole až do n tého pole (předposlední), např. se vstupem odděleným tabulátory:

n=$(head -n 1 infile | tr -dc \\t | tr \\t \\n | wc -l) cut -f1-$n infile > outfile 

nebo např.se souborem csv :

n=$(head -n 1 infile | tr -dc , | tr , \\n | wc -l) cut -d, -f1-$n infile > outfile 

Některá měřítka spustím později, pokud mám čas, ale s velkým vstupem si myslím, že to řešení by mělo být rychlejší než jiná řešení, která používají regex, protože ten na prvním řádku provádí minimální zpracování, aby získal počet polí, a poté použije cut, které je optimalizováno pro tuto práci.

Odpověď

Přenosně můžete použít některou z těchto možností:

sed "s/[[:space:]]*[^[:space:]]*$//" file awk "{sub(/[[:space:]]*[^[:space:]]*$/,"")}1" file 

Odpověď

Použití vim:

Otevřít soubor ve vim

vim <filename> 

Přejít na první řádek, pro případ, že by byl kurzor umístěn kdekoli jinde.

gg 

Vytvořte makro s názvem „q“ qq, který přejde na konec aktuálního řádku $, poté na poslední mezeru F (velká písmena F, následovaná doslovným VESMÍREM), poté odstraňte z aktuální pozice na konec řádku D přejděte na další řádek j a zastavte nahrávání makra pomocí q.

qq$F Djq 

Nyní můžeme naše makro opakovat s @q pro každý řádek.
Můžeme také stisknout @@ opakovat poslední makro nebo ještě snadněji:

99@q 

opakovat makro 99krát.
Poznámka: Počet se nesmí přesně shodovat s řádky.

Odpověď

U lidí, kteří mají podobný problém, ale mají různé oddělovače polí, toto awk zachová oddělovač pole správně:

$ cat file foo.bar.baz baz.bar.foo $ awk -F"." "sub(FS $NF,x)" file foo.bar baz.bar 

Napsat komentář

Vaše e-mailová adresa nebude zveřejněna. Vyžadované informace jsou označeny *