#
# Script Name : extract_filename.ksh
#
#!/bin/ksh
FILE_TO_SPLIT="CR_WKLY_Sales_SC_ON.TXT"
FILE_TO_SPLIT_NEW=$(awk FILE_TO_SPLIT_AWK="$FILE_TO_SPLIT" -F'[_.]' '{print $1"_"$3"_"$4"_"$5}')
echo "$FILE_TO_SPLIT_NEW"
次のコマンドはUnixコマンドプロンプトで正しく実行され、目的の出力を取得します。
echo "CR_WKLY_Sales_SC_NC.txt" | awk -F'[_.]' '{print $1"_"$3"_"$4"_"$5}'
抽出しようとしています。CR_Sales_SC_ON.TXT上記のスクリプトからファイル名から「WKLY」を削除すると、私が間違っているのでしょうか?
抑制する他の良い方法がありますか?キングケリー文字列CR_WKLY_Sales_SC_ON.TXTシェルスクリプトの文字列..?
WKLY
私の例を示すために何でもすることができます。私たちの要件は、最初の " _
"(アンダースコア)と2番目の " _
"(アンダースコア)の間に抑制された文字列を抽出することです。
例えば。
CR_MNTHLY_In2_SC_NC.txt
CR_WKLY_Sales_ST_NC.txt
CR_YRLY_In2_ST_NC.txt
CR_DLY_ITr_SC_NC.txt
必要な出力は次のようになります。
CR_In2_SC_NC.txt
CR_Sales_ST_NC.txt
CR_In2_ST_NC.txt
CR_ITr_SC_NC.txt
答え1
下線のいずれかを削除したいとします。以下を使用するソリューションは次のとおりですsed
。
$ echo CR_WKLY_Sales_SC_ON.TXT | sed 's/WKLY_//'
CR_Sales_SC_ON.TXT
答え2
必須ですawk
か?
sed
仕事に適した直感的な代替用途
sed -e 's/\(^[^_]*\)_[^_]*\(.*\)/\1\2/' u
CR_In2_SC_NC.txt
CR_Sales_ST_NC.txt
CR_In2_ST_NC.txt
CR_ITr_SC_NC.txt
u
ファイル(または入力)はどこにありますか?
単一変数の場合
FILE_TO_SPLIT_NEW=$(echo "$FILE_TO_SPLIT" | sed -e 's/\(^[^_]*\)_[^_]*\(.*\)/\1\2/')
sed 構文:
/\(^[^_]*\)_[^_]*\(.*\)/
このフィルタは Pattern1_pattern2_rest で、ここでパターンと残りは_
。[^_]*
「下線を除くすべての回数、回数制限」を意味します。- モード1と残りは変数に割り当てられます。
\(...\)
/\1\2/
変数拡張-e
個別置換は省略可能
答え3
実際の問題は、変換したい文字列をawk
スクリプトの呼び出しに渡す方法だと思います。これがFILE_TO_SPLIT_AWK="$FILE_TO_SPLIT"
@terdonがこれが何を意味するのかを尋ねる理由です。
正しい方法の1つは次のとおりです。
FILE_TO_SPLIT_NEW=$(echo "$FILE_TO_SPLIT" | awk -F'[_.]' '{print $1"_"$3"_"$4"_"$5}')
.txt
また、コマンドラインの例では、そうでないファイル名のサフィックス(あなたの場合)が出力に残りたいので、次のことを行う必要があります。
.
フィールド区切りリストにピリオドを含めないでください。最後のフィールドも印刷します。
だからどちらにしても
awk -F'_' '{print $1"_"$3"_"$4"_"$5}'
またはawk -F'[_.]' '{print $1"_"$3"_"$4"_"$5"."$6}'
とにかく、「_」で区切られた実際のフィールドの数に関係なく、2番目のフィールドのみを計算したい場合は、次の例が機能します。
FILE_TO_SPLIT_NEW=$(echo "$FILE_TO_SPLIT" | awk '{match($0,"^([^_]+)_([^_]+)_([[:print:]]*)$",a); print a[1]"_"a[3]}')
付録
パイプの使用によるコンテキスト切り替えを回避するには、最初に変換したいファイル名を一時ファイルとして作成してから、awk
メモリ内変数の代わりにそのファイルを操作できます。
echo $FILE_TO_SPLIT > tmpfile.txt
FILE_TO_SPLIT_NET=$(awk '{match($0,"^([^_]+)_([^_]+)_([[:print:]]*)$",a); print a[1]"_"a[3]}' tmpfile.txt)
ただし、(もちろん、特定のユースケースに応じて)すべての「元の」ファイル名をファイルに書き込んで、そのファイルを操作しawk
、結果を1行ずつ読み込むことで、変換されたすべてのファイル名を処理できます。
答え4
おそらく
cut -d_ -f1,3- file
-d_
区切り記号と出力-f
フィールド 1、3 以上の設定1,3-
出力
CR_In2_SC_NC.txt
CR_Sales_ST_NC.txt
CR_In2_ST_NC.txt
CR_ITr_SC_NC.txt
変数/文字列
cut -d_ -f1,3- <<<"CR_Banana_IN2_SC_NC.txt"
または
echo "CR_Banana_IN2_SC_NC.txt" | cut -d_ -f1,3-