次のファイルのリストがあります。
[root@ods1 backup]# ls -l
total 93892810
-rw-r----- 1 root root 651248 Feb 17 08:34 abc_def_g_17-02-2022.sql
-rw------- 1 root root 665248 Mar 23 08:46 bbc_23-03-2022.sql
-rw-r----- 1 root root 676992 Apr 04 16:52 zz_b_04-04-2022.sql
私が達成しなければならないことは次のとおりです。
abc_def_g
bbc
zz_b
私は成功せずにこれを試しました。
ls -l | awk '{print $9}' | cut -d '_' -f1-2
この目標をどのように達成できますか?最後の行まで一連のコマンドを取得します。_キャラクターは職業に依存しなければなりません。
編集:このコマンドはCentOS 8で実行されます。
答え1
到着解析されないls
loop
、シンプルで構文を使用できますshell
。
for f in *; do echo "${f%_*}"; done
リストをさらに処理する必要がある場合(および配列で作業できるシェルがある場合)、項目を配列に追加できます。
tokens=()
for f in *; do tokens=("${tokens[@]}" "${f%_*}"); done
echo "${tokens[@]}"
あるいは、ループを使わずに配列を直接宣言します。
files=(*)
tokens=("${files[@]%_*}")
#or
for token in "${files[@]%_*}"; do echo "$token"; done
答え2
次のように試すことができます。
ls|awk -F_ '{NF-=1}1' OFS=_
ここでの秘密は、フィールド数を1つずつ減らすことです(最後のフィールドを削除)。
答え3
zsh
シェルから:
print -r -C1 -- *_*.sql(Ne['REPLY=${REPLY%_*}'])
*_*.sql
これは、glob修飾子を使用して、最後の下線を含む最後の下線の後のすべての項目を削除し、指定されたglobパターンに一致する名前を変更します。実際の置換は標準パラメータ置換を使用して行われます。
結果文字列を使用して印刷以外の操作を実行するには、代わりにワイルドカードパターンを使用しますprint
(たとえば、for
ループ内または他のコマンドの引数として)。print
上記のコマンドをコマンド置換に入れないでください。
答え4
$ awk 'BEGIN{for (i=1;i<ARGC;i++) { f=ARGV[i]; sub(/_[^_]*$/,"",f); print f }; delete ARGV}' *
abc_def_g
bbc
zz_b
これは、ファイル名に改行文字やその他の文字が含まれている場合にも機能します。