daftar di skrip shell bash

Saya membuat skrip ini

#!/bin/bash

liste=`ls -l`
for i in $liste
do
    echo $i
done

Masalahnya adalah saya ingin skrip menampilkan setiap hasil baris demi baris, tetapi menampilkan kata demi kata:

Saya memiliki :

my_name
etud 
4096
Oct
8
10:13

dan saya ingin memiliki:

my_name etud 4096 Oct 8 10:13

Tujuan akhir dari skrip ini adalah untuk menganalisis setiap baris; itulah alasan saya ingin dapat memulihkan seluruh lini. Mungkin daftar tersebut bukan solusi terbaik tetapi saya tidak tahu bagaimana memulihkan garis tersebut.


person federem    schedule 10.10.2013    source sumber
comment
kemungkinan duplikat Bagaimana Anda memproses output perintah di shell baris demi baris?   -  person Mark Reed    schedule 10.10.2013
comment
@federem Mengapa Anda tidak memberi tahu kami informasi spesifik apa yang Anda inginkan dari saluran tersebut? Stempel waktu? Ukuran? Ada cara yang lebih baik untuk mendapatkan hal-hal tersebut, tidak melibatkan ls.   -  person Charles Duffy    schedule 11.10.2013


Jawaban (5)


Untuk memulai, kami berasumsi bahwa tidak ada nama file Anda yang berisi baris baru:

ls -l | IFS= while read -r line; do
    echo "$line"
    # Do whatever else you want with $line
done

Jika nama file Anda bisa berisi baris baru, segalanya menjadi rumit. Dalam hal ini, lebih baik (walaupun lebih lambat) menggunakan stat untuk mengambil metadata yang diinginkan dari setiap file satu per satu. Konsultasikan man stat untuk detail tentang cara kerja variasi stat lokal Anda, karena sayangnya variasi ini tidak terlalu terstandarisasi.

for f in *; do
    line=$(stat -c "%U %n %s %y" "$f")  # One possibility
    # Work with $line as if it came from ls -l
done
person chepner    schedule 10.10.2013
comment
BENAR. Namun, jika Anda harus menjalankan proses baru untuk setiap file, kontrol atas output yang diizinkan stat mungkin lebih nyaman. (Tapi ya, saya mengabaikan bahwa Anda dapat memanggil ls untuk setiap file.) - person chepner; 11.10.2013

Anda bisa menggantinya

echo $i

dengan

echo -n "$i "

echo -n keluaran ke konsol tanpa baris baru.

person Fabrice Jammes    schedule 10.10.2013
comment
echo -n bukan standar POSIX. printf adalah pendekatan yang aman dan portabel. - person Charles Duffy; 10.10.2013
comment
@Charles Duffy, ini didefinisikan dalam IEEE Std 1003.1-2001 POSIX. - person Jim Black; 10.10.2013
comment
@JimBlack Hanya sebagai ekstensi XSI. - person Charles Duffy; 11.10.2013
comment
@JimBlack kutipan: System V echo tidak mendukung opsi apa pun, tetapi memungkinkan urutan escape dalam operannya, seperti yang dijelaskan untuk implementasi XSI di bagian OPERANDS. Kutipan lain: Tidak mungkin menggunakan echo secara portabel di semua sistem POSIX kecuali -n (sebagai argumen pertama) dan urutan escape dihilangkan. - person Charles Duffy; 11.10.2013

Cara lain untuk melakukannya dengan loop sementara dan tanpa pipa:

#!/bin/bash

while read line
do
    echo "line: $line"
done < <(ls -l)
person Labynocle    schedule 10.10.2013
comment
Ini benar (kecuali untuk menggunakan read tanpa -r -- sehingga urutan escape diinterpretasikan -- dan membiarkan $IFS pada default -- dan dengan demikian spasi di belakangnya dihapus), jika tujuannya adalah untuk mendemonstrasikan pembacaan dari aliran. Tidak benar, jika tujuannya adalah untuk mendemonstrasikan pembacaan daftar file (beberapa orang benar-benar berpikir bahwa ls adalah cara yang tepat untuk melakukan ini!). Akan lebih baik jika jawabannya lebih jelas. - person Charles Duffy; 10.10.2013

Pertama, saya harap Anda tidak benar-benar menggunakan ls dalam kode asli Anda, tetapi hanya menggunakannya sebagai contoh. Jika Anda menginginkan daftar file, ls adalah alat yang salah; lihat http://mywiki.wooledge.org/ParsingLs untuk detailnya.

Kedua, versi modern dari bash memiliki builtin yang disebut readarray.

Coba ini:

readarray -t my_array < <(ls -l)
for entry in "${my_array[@]}"; do
  read -a pieces <<<"$entry"
  printf '<%s> ' "${pieces[@]}"; echo
done

Pertama, ia membuat sebuah array (disebut my_array) dengan semua output dari perintah yang dijalankan.

Kemudian, untuk setiap baris dalam keluaran itu, ia membuat larik bernama pieces, dan memancarkan setiap bagian dengan tanda kurung panah di sekelilingnya.

Jika Anda ingin membaca satu baris sekaligus, daripada membaca keseluruhan berkas sekaligus, lihat http://mywiki.wooledge.org/BashFAQ/001 ("Bagaimana cara membaca file (aliran data, variabel) baris demi baris (dan/atau bidang demi bidang)?")

person Charles Duffy    schedule 10.10.2013
comment
<(ls -l) akan gagal dalam kondisi yang sama seperti ls -l | while read.... - person chepner; 10.10.2013
comment
@chepner Jika maksud Anda spesifik ls, saya yakin saya tidak pernah menyiratkan hal sebaliknya -- lihat paragraf pertama jawaban saya. (Oleh karena itu, kecuali Anda tidak mempertimbangkan kehilangan status lokal proses apa pun terkait dengan konten yang Anda baca gagal, saya tidak setuju dengan keakuratan keberatan dalam kasus umum dan non-spesifik) - person Charles Duffy; 11.10.2013

Menggabungkan jawaban sebelumnya dengan kebutuhan untuk menyimpan daftar file dalam suatu variabel. Kamu bisa melakukan ini

echo -n "$list"|while read -r lin
do
 echo $lin
done
person FeLocci    schedule 10.10.2013