#
# 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
내 예를 보여주기 위해 무엇이든 될 수 있습니다. 우리의 요구 사항은 첫 번째 " _
"(밑줄)과 두 번째 " _
"(밑줄) 사이에 억제된 문자열을 추출하는 것입니다.
예를 들어.
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이 이것이 무엇을 의미하는지 질문하는 이유입니다.
올바른 방법 중 하나는 다음과 같습니다.
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}'
어쨌든 "_"로 구분된 실제 필드 수와 무관하고 두 번째 필드만 계산하려는 경우 다음 예가 작동합니다.
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
해당 파일에 대해 작업하고, 결과를 한 줄씩 읽어 변환된 모든 파일 이름을 처리할 수 있습니다.
답변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-