ファイルがありますabc_asdfjhdsf_ckd_dfksfj_c_12345678_223344.txt
。出力になりたいですabc_asdfjhdsf_ckd_dfksfj_c.txt
。
答え1
sedを使う
$ echo abc_* | sed -E 's/(([^_]*_){5}).*/\1/; s/_$/.txt/'
abc_asdfjhdsf_ckd_dfksfj_c.txt
仕組み:
s/(([^_]*_){5}).*/\1/
これにより、グループ1(最大5番目)のファイル名の先頭がキャプチャされ、残りは
_
削除されます。もっと詳しく見ると、sedの代替コマンドは次の形式を持っています。正規表現は
s/old/new/
どこにありますか?old
この例では、正規表現は([^_]*_){5}
最初の5つの部分と一致します。この正規表現を括弧内に入れて、最初の5つの部分をグループ1に保存します。(([^_]*_){5})
これを。最初の5つのグループ以降のすべての項目と一致します。私達はこれらすべてを最初の5つのグループである 。\1
.*
\1
s/_$/.txt/
それから最後の残りを
_
見つけて.txt
。
awkを使う
$ echo abc_* | awk -F_ '{print $1,$2,$3,$4,$5 ".txt"}' OFS=_
abc_asdfjhdsf_ckd_dfksfj_c.txt
_
これは入力フィールドと出力フィールドの区切り文字として使用されます。したがって、最初の5つのフィールドを印刷し、その後に.txt
。
回避策:最後の2つの部分を削除してください。
上記のコードは最初の5つの部分を保持し、残りの部分を削除します。質問の例には7つのセクションがあり、どちらもピリオドを含みません。 いつもそうだったらもう1つのアプローチ(ヒント:Costas)は、最後の2つの部分を削除することです。
$ echo abc_* | sed -E 's/(_[^_]*){2}\././'
abc_asdfjhdsf_ckd_dfksfj_c.txt
答え2
ファイルの終わりの名前を変更する元の質問を参照すると、次のようになります。
ls abc*
abc_asdfjhdsf_ckd_dfksfj_c_12345678_223344.csv
ls abc* | cut -d_ -f1-5 | awk '{print $1".txt";}'
abc_asdfjhdsf_ckd_dfksfj_c.txt
答え3
for f in ./*_*_*_*_*_?*.txt
do [ -e "$f" ] &&
printf %s.txt\\n "${f%"${f#*_*_*_*_*_?}"}"
done
答え4
使用bash
パラメータ拡張:
for f in abc_*; do f="${f%_*}"; echo "${f%_*}.txt"; done
出力:
abc_asdfjhdsf_ckd_dfksfj_c.txt
${f%_*}
f
_
最後の(含まれている)変数以降のすべての項目を削除した後に変数値を含むパラメータ拡張モード。