
다음 형식의 파일이 있습니다.
ABCD 01206001022T01YA022T01YA022T07SO 09:20:38
ABCD 01206001022ACION 09:24:40
ABCD 04006001021S01UK 09:24:42
ABCD 7878696621321312 23213213213213
ABCD ASADSADSFSSDSSD 09:24:50
기본적으로 첫 번째 필드를 제외한 모든 필드는 다릅니다.
요구 사항: 각 행에 타임스탬프가 있기를 원합니다. 타임스탬프가 누락된 행이 있는 경우 이전 행의 타임스탬프를 누락된 행의 끝에 추가하고 싶습니다(위 예의 4행). 이 목표를 어떻게 달성할 수 있나요?
답변1
이렇게 하면 awk
트릭을 수행할 수 있습니다.
awk '{
if ( $NF ~ /[0-9]+:[0-9]+:[0-9]+/ ) {
lasttime = $NF
print
} else {
print $0, lasttime
}
}' < myfile.txt
답변2
만약을 대비해 bash 솔루션이 있습니다. 단일 항목을 사용 awk
하지만 필요한 경우 리팩터링될 수 있습니다.
while read line ; do
ncol=$(echo "$line" | awk '{print $NF}')
if [[ "$ncol" == *:*:* ]]; then
tmstmp="$ncol"
echo "$line"
continue
fi
echo "$line $tmstmp"
done < 82031.txt
파일에는 82031.txt
다음 내용이 포함됩니다.
ABCD 01206001022T01YA022T01YA022T07SO 09:20:38
ABCD 01206001022ACION 09:24:40
ABCD 04006001021S01UK 09:24:42
ABCD 7878696621321312 23213213213213
ABCD ASADSADSFSSDSSD 09:24:50
위 스크립트를 실행하면 다음과 같은 결과가 생성됩니다.
ABCD 01206001022T01YA022T01YA022T07SO 09:20:38
ABCD 01206001022ACION 09:24:40
ABCD 04006001021S01UK 09:24:42
ABCD 7878696621321312 23213213213213 09:24:42
ABCD ASADSADSFSSDSSD 09:24:50
순수 Bash 솔루션
이것은 Bash 전용 대안입니다. awk
.txt 파일의 입력 줄에서 마지막 열을 추출하는 대신 read
루프에서 Bash 명령을 사용 합니다 while
. 이러한 옵션은 -ra
백슬래시를 이스케이프 문자( -r
)로 비활성화하고 -a
구분 기호를 사용하여 입력을 분할하여 $IFS
각 원자의 텍스트를 배열의 요소에 배치합니다 ${line[@]}
.
while IFS=" " read -ra line ; do
ncol="${line[@]: -1:1}"
if [[ "$ncol" == *:*:* ]]; then
tmstmp="$ncol"
echo "${line[@]}"
continue
fi
echo "${line[@]} $tmstmp"
done < 82031.txt
이 비트는 ${line[@]: -1:1}
배열의 마지막 열을 추출합니다 ${line[@]}
.
답변3
또 다른 bash 솔루션
[[ ! -f $1 ]] && { echo -e "\tUsage:\t\n\t\t$0\t<input_file>\n"; exit 1; }
while read -ra line;
do
if [[ ${line[@]} =~ [0-9]+:[0-9]+:[0-9]+ ]]; then
echo ${line[@]}
lasttime=${line[@]: -1:1}
else
echo ${line[@]} $lasttime
fi
done < $1