Как удалить заголовок оставшихся пробелов после удаления множества полей? - PullRequest
1 голос
/ 01 ноября 2019

(извините, но я напишу "I" как "i", потому что "I" всегда путают с символом канала;)

У меня есть файл tar, поэтому я могу видеть список с помощью "-т "вариант. каждая строка будет как ниже.

-rwxr-x--- admin/users  287110 2017-04-01 12:49 017_0401/345 alice.wav

мы можем видеть, что путь - "017_0401 /", а имя файла - "345 alice.wav", в котором есть пробел.

и что мне нужнопросто имя файла и информация о размере.

для "awk", $ 3 - это размер, $ 6, а остальная часть будет именем файла.

к сожалению, многие из файлов имеют непредсказуемое количество пробелов в именах. (не назван мной).

Я хочу, чтобы "awk" сделал этот список таким, как показано ниже. ("filename" \ t "size")

017_0401/345 alice.wav [tab] 287110

Итак, я попробовал "awk" следующим образом:

   cat tarlist.txt | awk '{zsize=$3; $1=$2=$3=$4=$5=""; print $0"\t"zsize;}'
   #rem: i had to use $0 because many files have spaces in the name.

, но результат будет иметь пробелы, как показано ниже.

[5spaces]017_0401/345 alice.wav [tab] 287110

что мне нужно, это как ...

017_0401/345 alice.wav [tab] 287110

что я могу сделать, чтобы удалить оставшиеся пробелы из 5 удаленных полей? спасибо за чтение до здесь.

Ответы [ 3 ]

3 голосов
/ 01 ноября 2019

Этот вид простой замены в отдельных строках - это то, для чего был создан sed. С GNU sed для -E и \s/\S:

$ echo '-rwxr-x--- admin/users  287110 2017-04-01 12:49 017_0401/345 alice.wav' |
    sed -E 's/^(\S*\s*){2}(\S*)\s*(\S*\s*){2}(.*)/\4\t\2/'
017_0401/345 alice.wav  287110

С любым POSIX sed:

$ echo '-rwxr-x--- admin/users  287110 2017-04-01 12:49 017_0401/345 alice.wav' |
    sed 's/^\([^[:space:]]*[[:space:]]*\)\{2\}\([^[:space:]]*\)[[:space:]]*\([^[:space:]]*[[:space:]]*\)\{2\}\(.*\)/\4\t\2/'
017_0401/345 alice.wav  287110

Если вы предпочитаете awk, с GNU awk для \s/\S:

$ echo '-rwxr-x--- admin/users  287110 2017-04-01 12:49 017_0401/345 alice.wav' |
    awk -v OFS='\t' '{size=$3; sub(/^(\S+\s+){5}/,""); print $0, size}'
017_0401/345 alice.wav  287110

или с любым POSIX awk:

$ echo '-rwxr-x--- admin/users  287110 2017-04-01 12:49 017_0401/345 alice.wav' |
    awk -v OFS='\t' '{size=$3; sub(/^([^[:space:]]+[[:space:]]+){5}/,""); print $0, size}'
017_0401/345 alice.wav  287110

Выше будет работать до тех пор, пока ваши имена файлов не могут содержать переводы строк.

3 голосов
/ 01 ноября 2019

Удалите все начальные пробелы из $0 с помощью GNU awk:

tar ... | awk '{size=$3; $1=$2=$3=$4=$5=""; gsub(/^ */, ""); print $0 "\t" size}'
1 голос
/ 01 ноября 2019

Немного другой дубль ... удалить все до двоеточия (:) и трех символов после него:

tar tvf ... | gawk '{print gensub(/[^:]*:...(.*)/,"\\1\t"$3,1)}'

Это все равно будет работать, даже если имя файла / каталога начинается спространство. Для новичков в awk это говорит ...

"Захват всего, что следует за двоеточием и тремя последующими символами, в качестве группы захвата 1. Распечатайте группу захвата 1, за которой следуют вкладка и поле 3. Делайте это только при первом появлении двоеточия. "

Обратите внимание, что для gensub() требуется GNU awk. См. Комментарий Эда Мортона.


Если вы действительно хотите "кодировать гольф" и сделать его короче, более загадочным и неразборчивым, вы можете использовать:

tar ... | gawk '{$0=gensub(/.*:...(.*)/,"\\1\t"$3,1)}1'
...