Як вивести лише імена файлів (з пробілами) у ls -Al?


78

Я повинен перегукуватися лише з іменами файлів чи каталогів з цією конструкцією:

ls -Al | while read string
do
...
done

ls -Al вихід:

drwxr-xr-x  12 s162103  studs         12 march 28 12:49 personal domain
drwxr-xr-x   2 s162103  studs          3 march 28 22:32 public_html
drwxr-xr-x   7 s162103  studs          8 march 28 13:59 WebApplication1

Наприклад, якщо я спробую:

ls -Al | while read string
do
echo "$string" | awk '{print $9}
done

потім виводити лише файли та каталоги без пробілів. Якщо у файлі чи каталозі є пробіли типу "персональний домен", це буде лише слово "особистий".

Мені потрібно дуже просте рішення. Можливо, є краще рішення, ніж awk.


2
Чому б не просто ls -Al *' '*? Результати парсингу lsніколи не призводять до нічого доброго.
манатурка

1
Якщо вам потрібно щось, що буде працювати в будь-якому * nix, спробуйте уникати використання ls -Al | while. Простий і надійніший спосіб for string in *; do echo "$string"; done.
forcefsck

потрібно лише з цією конструкцією .. добре, не просто, будь-яке рішення!
Алекс Зерн

1
Навіщо вам це потрібно ls ? Розбір lsі "робота у всіх * nix і не зламаються, якщо щось трапилося", не йдуть добре разом.
тердон

Відповіді:


97

Ви дійсно не повинні розбирати вихідls . Якщо це домашнє завдання, і ви цього вимагаєте, ваш професор не знає, про що вони говорять. Чому б ти не зробив щось подібне:

Добре ...

find ./  -printf "%f\n"

або

for n in *; do printf '%s\n' "$n"; done

... поганий ...

Якщо ви дійсно хочете використовувати ls, ви можете зробити це трохи надійніше, зробивши щось подібне:

ls -lA | awk -F':[0-9]* ' '/:/{print $2}'

... і потворне

Якщо ви наполягаєте на тому, щоб зробити це неправильним, небезпечним способом і просто потрібно використовувати whileцикл, зробіть це:

ls -Al | while IFS= read -r string; do echo "$string" | 
    awk -F':[0-9]* ' '/:/{print $2}'; done

Якщо серйозно, то просто не варто.


drwx------ 2 s162103 studs 3 oct. 9 2012 .ssh drwxr-xr-x 3 s162103 studs 6 oct. 25 09:02 .subversion drwxrwxrwt 3 s162103 studs 3 nov. 15 2012 .TempoItemsінколи у мене є дата без часу, лише рік і
гаук

1
@AlexZern Ну, це одна з причин, коли ти не розбираєш результат ls.
terdon

2
@AlexZern навіщо вам потрібен -lперемикач? Якщо ви хочете лише назвати файли, просто запустіть ls -A. Використання -lпросто ускладнює ваше життя, оскільки вам зараз доведеться розбирати результати.
тердон

тому що мені потрібна додаткова інформація, як доступ, дата, власник тощо. І я написав величезний сценарій, який добре працює, за винятком імен файлів друку та режиму з пробілами.
Алекс Зерн

3
Добре тоді. Що у нас тут є проблема XY . lsпросто не найкращий спосіб отримати те, що потрібно. Чому б ви не опублікували нове запитання, в якому пояснюється інформація, яку ви хочете зібрати, і ми можемо запропонувати способи цього зробити. Крім того, ви можете використовувати свій сценарій таким, яким він є, і скористатися однією з пропозицій вище, щоб надрукувати лише ім’я. Але серйозно, не розбирайтеся ls, просто скажіть нам, що саме ви намагаєтесь зробити в новому запитанні.
terdon

74

Чи є якась причина, що ls -A1* не буде працювати?

Наприклад:

$ touch file1 file2 file\ with\ spaces
$ ls -Al
total 0
-rw-r--r-- 1 bahamat bahamat 0 Mar 30 22:31 file1
-rw-r--r-- 1 bahamat bahamat 0 Mar 30 22:31 file2
-rw-r--r-- 1 bahamat bahamat 0 Mar 30 22:31 file with spaces
$ ls -A1
file1
file2
file with spaces
$

* Примітка: це велика літера А і номер одна.


4
-1 геній. Я не знав, що це було доступно. (Я знаю, що знаю. RTFM)
Ледачий кодер

що працює лише для поточного каталогу, якщо ви хочете перелічити імена файлів з іншого каталогу, скажімо ~ /
project,

@thecotne на Mac 10.9.5 він просто перелічує назви файлів. Яку ОС ви використовуєте?
AJP

я запускаю цей ls ~ / projects / *. sublime-project -A1 для ls ~ / project -A1 я отримую лише імена
thecotne

3
@TheLazyCoder не слід було прочитати посібник.
c24w

41

Цікаво, чому ніхто не згадав про цю просту команду:

ls -a | sort

2
Блискуче! Будь-яка ідея, як трубопровід sortпризводить до того, що блок з декількома стовпцями не буде переданий в один стовпець?
msciwoj

@msciwoj він просто займає будь-які рядки, розділені пробілами, і друкує їх, відсортовані розділеними кінцевими лініями
Ben

ЗДОРОВИЙ! Чому цей не був позначений як справжня відповідь?
夏 期 劇場

3
Він працює тут, тому що lsповертається до ls -1(одного стовпчикового виводу), коли його вихід не переходить до терміналу (і вимикає недрукувальний символ котирування / заміни; @Kusalananda, ваш lsне сумісний з POSIX, якщо він все-таки є). lsвихід вже відсортований. Тож його трубопровід sortу кращому випадку нічого не зробить, а при гіршому виведенні виводу (якщо назви файлів містять символи нового рядка) або не вдасться до імен файлів, які не є текстовими. ls -a | catбуло б краще. Або ще краще, ls -A1як уже згадувалося (а тому, що ви, як правило, хочете заміни / цитування, коли вони відображаються на терміналі)
Stéphane Chazelas

1
@ StéphaneChazelas Помічено. lsповодиться інакше, коли вихід не є терміналом.
Кусалаланда

3

Ви не можете проаналізувати вихід ls, не кажучи вже про те, ls -lщо новий рядок, як і пробіл, є таким же дійсним символом, як і будь-який в імені файлу. Крім того, вам потрібно буде врахувати символьні посилання, які мають вихід ... foo -> bar.

Чому б ви -lвсе-таки використовували, якщо ви хочете лише ім'я файлу?

Просто зробіть:

for file in *; do
  ...
done

Якщо ви хочете включити крапкові файли (крім .і ..), залежно від оболонки:

zsh:

for file in *(ND); do
  ...
done

bash:

shopt -s nullglob dotglob
for file in *; do
  ...
done

ksh93:

FIGNORE='@(.|..)'
for file in ~(N)*; do
  ...
done

POSIXly:

for file in .[!.]* ..?* *; do
  [ -e "$file" ] || [ -L "$file" ] || continue
  ...
done


1
ls -Al | tr -s ' ' | cut -f9- -d' '

стиснути кілька пробілів в одиничні проміжки з tr, тоді ви можете використовувати cut для розділення на поля


1

Спробуйте ( bash, zsh, ksh93синтаксис):

find . -type f -print0 | while IFS= read -r -d '' filename; do
  ...
done

Це стає рекурсивним і перераховується лише у звичайних файлах (тобто немає dirs або symlinks / fifos / devices ...).

Дивитися також:



Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.