awk '{print $ 9}' последний столбец ls -l, включая все пробелы в имени файла - PullRequest
16 голосов
/ 19 сентября 2009

Как получить awk для вывода полного имени файла в ls -l, если в некоторых файлах есть пробелы. Обычно я могу запустить эту команду:

ls -l | awk '{print $9}'

Это не работает, если в файлах есть пробелы. Можно ли как-то напечатать 9, 10, 11 и т. Д.?

Ответы [ 7 ]

33 голосов
/ 19 сентября 2009

Лучшее решение: не пытайтесь сначала проанализировать вывод ls.

Официальная вики на канале irc.freenode.org #bash объясняет, почему это плохая идея, и какие альтернативные подходы вы можете использовать вместо: http://mywiki.wooledge.org/ParsingLs

Использование команды find, stat и аналогичных инструментов обеспечит требуемую функциональность без ошибок (не все из них очевидны - некоторые возникают только при переходе на платформы с различными реализациями ls) .

Для вашего конкретного примера я предполагаю, что вы пытаетесь найти только файлы (а не каталоги) в вашем текущем каталоге; Ваша текущая реализация, использующая ls -l, содержит ошибки, так как исключает файлы с разрешениями + t или setuid. Правильный путь для реализации этого будет следующим:

find . -maxdepth 1 -type f -printf '%f\n'
3 голосов
/ 21 сентября 2009

Просто для завершения. Это также можно сделать с помощью sed:

# just an exercise in regex matching ...
ls -l | sed -E  -e '1d; s/^([^ ]+ +){8}//' 
2 голосов
/ 19 сентября 2009

Если вы все еще настаиваете на ls -l вместо find или других инструментов, вот мое решение. Это не красиво и не разрушительно:

  1. Уничтожьте $ 1 .. $ 8, установив для них значение "" через цикл for
  2. Если до 9 $ осталось несколько пробелов, удалите их с помощью команды sub ()
  3. Распечатайте оставшиеся
ls -l | awk '{for (i = 1; i < 9; i++) $i = ""; sub(/^ */, ""); print}'
1 голос
/ 16 октября 2015
ls -l | awk -v x=9 '{print $x}'

Я использую это для получения имен каталогов без инцидентов. Я заметил, что решение find отлично подходит, если вы не уверены в типах файлов, если вы знаете, что вы смотрите на ls -l, работает отлично, по умолчанию в алфавитном порядке.

1 голос
/ 20 марта 2014

Решение состоит в том, чтобы кодировать и декодировать пространство словом или символом, используя sed:

ls -l | sed s/\ /{space}/ | awk '{print $9}' | sed s/{space}/\ /

Это заменит все пробелы в строке на {space} перед передачей в awk. После того, как строка перешла на awk, мы заменяем {space} обратно пробелом.

find, как утверждают другие, является гораздо лучшим решением. Но если вам действительно нужно использовать awk, вы можете попробовать это.

1 голос
/ 19 сентября 2009
echo 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 | 
  awk 'BEGIN {OFS=ORS=""} ; {for (i=9;i<NF;i++) print $i " "; print $NF "\n"}'
1 голос
/ 19 сентября 2009

Вероятно, есть лучший подход, который предполагает как-то комбинирование полей, но:

$ echo 1 2 3 4 5 6 7 8 9 10 11 12 13 14... | 
  awk '{for (i = 9 ; i <= NF ; i++) printf "%s ", $i}'
9 10 11 12 13 14... 

Использование printf "%s " $i напечатает i-ое поле с пробелом после него, а не перевод строки. Цикл for просто говорит, что нужно перейти от поля 9 к последнему полю.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...