Iterasi pada setiap baris output ls -l

120

Saya ingin mengulang setiap baris dalam output dari: ls -l /some/dir/*

Saat ini saya sedang mencoba: for x in $(ls -l $1); do echo $x; done

Namun, ini mengulangi setiap elemen di baris secara terpisah, jadi saya mendapatkan:

-r--r-----
1
ivanevf
eng
1074
Apr
22
13:07
File1

-r--r-----
1
ivanevf
eng
1074
Apr
22
13:17
File2

Tapi saya ingin mengulang setiap baris secara keseluruhan. Bagaimana aku melakukan itu?

Ivan
sumber
1
Selalu kutip variabel (dan keluaran perintah) kecuali Anda memiliki alasan khusus untuk tidak melakukannya.
glenn jackman

Jawaban:

247

Setel IFS ke baris baru, seperti ini:

IFS='
'
for x in `ls -l $1`; do echo $x; done

Letakkan sub-shell di sekitarnya jika Anda tidak ingin mengatur IFS secara permanen:

(IFS='
'
for x in `ls -l $1`; do echo $x; done)

Atau gunakan saat | baca saja:

ls -l $1 | while read x; do echo $x; done

Satu opsi lagi, yang menjalankan while / read pada level shell yang sama:

while read x; do echo $x; done << EOF
$(ls -l $1)
EOF
Randy Proctor
sumber
12
Hati-hati saat melakukan piping ke while, while akan berjalan di subkulit, yang berarti tidak bisa mengubah variabel dalam proses utama
Reorx
1
Apa yang dilakukan $ 1 di sini? Saya perlu menggunakan ini dalam skrip yang saya tulis yang menerima argumen. $ 1 membuang banyak hal. Apa yang bisa saya taruh di sana selain $ 1 untuk mendapatkan efek yang sama? Saya ingin menggunakan solusi kedua.
noob-in-need
@ noob-in-need Gantilah dengan direktori apa pun yang ingin Anda daftarkan
vpzomtrrfrt
1
Anda mungkin ingin melakukannya read -ratau bash akan menghapus garis miring terbalik yang tidak terhindarkan dari data.
Brian Gordon
6

Itu tergantung apa yang ingin Anda lakukan dengan setiap baris. awk adalah utilitas yang berguna untuk jenis pemrosesan ini. Contoh:

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

.. di sistem saya mencetak nama dan ukuran setiap item dalam direktori.

Adam Holmberg
sumber
3

Seperti yang telah disebutkan, awk adalah alat yang tepat untuk ini. Jika Anda tidak ingin menggunakan awk, alih-alih mem-parsing keluaran "ls -l" baris demi baris, Anda dapat mengulangi semua file dan melakukan "ls -l" untuk setiap file seperti ini:

for x in * ; do echo `ls -ld $x` ; done
Axel
sumber
3

Anda juga dapat mencoba findperintah tersebut. Jika Anda hanya ingin file di direktori saat ini:

find . -d 1 -prune -ls

Jalankan perintah pada masing-masing?

find . -d 1 -prune -exec echo {} \;

Hitung baris, tetapi hanya dalam file?

find . -d 1 -prune -type f -exec wc -l {} \;

David Koski
sumber
temukan rusak. Saya sering mendapatkan beberapa pesan kesalahan yang aneh. itu ingin memberi saya bantuan ketika baris perintah benar-benar valid, dan sepertinya begitu mulai melakukan ini, itu tidak akan berhenti sampai reboot berikutnya MUNGKIN. kadang-kadang tampak acak di alam tentang kesalahan. tidak yakin bagaimana saya dapat melaporkan bug tersebut.
Jim Michaels
1

Utilitas read (1) bersama dengan pengalihan keluaran dari perintah ls (1) akan melakukan apa yang Anda inginkan.

Steve Emmerson
sumber
-1

Jadi, mengapa tidak ada yang menyarankan hanya menggunakan opsi yang menghilangkan bagian yang tidak ingin dia proses.

Di Debian modern, Anda cukup mendapatkan file Anda dengan:

ls --format=single-column 

Lebih jauh lagi, Anda tidak perlu memperhatikan direktori tempat Anda menjalankannya jika Anda menggunakan direktori lengkap:

ls --format=single-column /root/dir/starting/point/to/target/dir/

Perintah terakhir ini saya gunakan di atas dan saya mendapatkan output berikut:

bot@dev:~/downloaded/Daily# ls --format=single-column /home/bot/downloaded/Daily/*.gz
/home/bot/downloaded/Daily/Liq_DailyManifest_V3_US_20141119_IENT1.txt.gz
/home/bot/downloaded/Daily/Liq_DailyManifest_V3_US_20141120_IENT1.txt.gz
/home/bot/downloaded/Daily/Liq_DailyManifest_V3_US_20141121_IENT1.txt.gz
BradChesney79
sumber