다음과 같은 수천 개의 파일이 있습니다.
조직 문서:
reference_group1 _CEFNB_
group1 ACBF_BG
group2 ACB_MBM
...
각 파일에 대해 행을 열로 변환한 다음 다음과 같이 reference_group의 인덱스로 구성된 열(id_from_reference_group이라고 함)을 추가해야 합니다.
변환된 파일
# explanation of each column
# reference_group_id serials_from_ref_group group_id serials_from_group
reference_group1 _ group1 A
reference_group1 group1 C
reference_group1 E group1 B
reference_group1 F group1 F
reference_group1 N group1 _
reference_group1 B group1 B
reference_group1 _ group1 G
reference_group1 _ group2 A
reference_group1 C group2 C
reference_group1 E group2 B
reference_group1 F group2 _
reference_group1 N group2 M
reference_group1 B group2 B
reference_group1 _ group2 M
org_files의 각 그룹에 있는 두 번째 열의 내용은 반복되는 문자로 구성됩니다. 그리고 두 번째 열의 길이는 항상 동일합니다.
나는 노력했다
input="reference_group1 _CEFNB_
group1 ACBF_BG
group2 ACB_MBM"
while IFS=" " read -ra line; do # read input line by line
# loop over fields
for (( i = 0 ; i < ${#line[@]}; i++ )); do
# only split 2nd field
if [[ $i == 1 ]]
then
for j in ${line[$i]}
do
# loopover each letter of 2nd field
for (( j=0; j<${#line[$i]}; j++ ))
do
echo "${line[$i-1]} ${line[$i]:$j:1}"
done
done
fi
done
done <<< "$input"
하지만 나는이 결과를 얻습니다
reference_group1 _
...
group1 A
...
group2 M
그리고 코드가 좀 지저분해요. 간단한 명령어가 있으면 더 좋을 것 같아요. 감사해요!
답변1
()와 같은 스크립트를 사용하여 awk를 사용할 수 있습니다 tst.awk
.
BEGIN{print "#reference_group_id serials_from_ref_group group_id serials_from_group"}
$1 ~ /^reference_/ {ref=$1;ser=$2;next}
{
for(i=1;i<=length($2);i++){
print ref, substr(ser,i,1), $1, substr($2,i,1)
}
}
내 생각에는 항상 reference_group_id
먼저 reference_
이름이 지정된 var에 저장한 ref
다음 serials_from_ref_group
에 저장합니다 ser
. 그런 다음 루프에서 두 변수를 모두 사용합니다.
그러면 다음과 같은 줄이 작동합니다.
awk -f tst.awk file
출력 형식이 지정되면 column
출력을 다음으로 파이프할 수 있습니다.column -t
awk -f tst.awk file | column -t
awk 스크립트에 대한 지침:
BEGIN
첫 번째 입력 레코드 이전에 한 번만 실행됩니다.$1 ~ /^reference_/
$1
정규 표현식과 일치하는 경우^reference_
length($2)
두 번째 필드의 길이substr(ser,i,1)
ser
위치와 길이 로i
시작하는 부분 문자열1