나는 꽤 큰 파일에 대해 간단한 텍스트 작업을 수행하려고 하는 경우가 많습니다. 다양한 Unix 텍스트 수정 도구 중 하나를 사용하여 이를 스크립트하는 방법이 있어야 할 것 같지만 정확히 어떻게 되는지는 모르겠습니다.
구체적인 예로 다음과 같은 소스 코드가 있다고 가정해 보겠습니다.
foo1 = undefined
foo2 = undefined
foo3 = foobar 7
foo4 = undefined
나는 이것을 다음과 같이 바꾸고 싶습니다 :
foo1 = error "foo1"
foo2 = error "foo2"
foo3 = foobar 7
foo4 = error "foo4"
그것좋다이 전환을 자동화할 수 있는 방법이 분명히 있을 것입니다. 분명 쉽게 할 수 있을 것 같은데프로그램을 작성하다실제 프로그래밍 언어로 하지만 이를 수행할 수 있는 몇 가지 명령줄 도구가 있습니다. (?)
좀 더 복잡한 예로, 어떻게 하면 될까요?
foo=ABC
bar=DEF
baz=GHI
foo=123
bar=456
baz=789
입력하다
Magic(ABC, DEF, GHI);
Magic(123, 456, 789);
보다 일반적으로 이러한 변환을 수행하려면 어떤 도구를 사용해야 합니까? 그게 sed
, 아니면 awk
, 아니면...?
답변1
구체적인 상황에 따라 다릅니다. 첫 번째 예는 또는 를 사용하여 sed
해결할 수 있습니다 awk
. 예를 들어 다음을 사용합니다 awk
.
$ awk '
/undefined/ {printf "%s = error \"%s\"\n", $1, $1; next}
{print}
' input
다음을 생성합니다.
foo1 = error "foo1"
foo2 = error "foo2"
foo3 = foobar 7
foo4 = error "foo4"
또는 다음을 사용하십시오 sed
.
sed '
/undefined/ s/\([^ ]*\) =.*/\1 = error "\1"/
' input
두 번째 예는 awk
Perl이나 Python과 같은 고급 언어를 사용하면 더 쉽게 수행할 수 있습니다. 다시 말하지만 awk
,
awk '
{
split($0, parts, "=")
items[i++] = parts[2]
}
i%3 == 0 {
printf "Magic(%s, %s, %s)\n", items[0], items[1], items[2]
i=0
}
' input
다음을 생성합니다.
Magic(ABC, DEF, GHI)
Magic(123, 456, 789)
좀 더 일반적으로 말하자면... 일반적인 답변을 드릴 수 있을지 모르겠습니다. 이는 실제로 달성하려는 특정 작업에 따라 다릅니다. 일단 나가면 awk
,프로그램을 작성하다안에실제 프로그래밍 언어, 따라서 Perl, Python, Ruby 등과 같은 고급 도구가 더 강력하다는 이유만으로 이를 기피해서는 안 됩니다.
답변2
sed
간단한 텍스트 조작에 적합합니다. 일반적으로 한 줄 편집이지만 (상당한 노력을 들여) 여러 줄을 처리할 수도 있습니다. 전반적으로 sed
변수와 산술 계산이 부족하여 상당히 제한적이지만 그럼에도 불구하고 많은 상황에서 가장 간단한 솔루션을 제공합니다.
awk
간단하고 복잡한 텍스트 조작 및 숫자 계산에는 적합하지만 다른 작업에는 적합하지 않습니다.
첫 번째 예는 다음과 같습니다.
sed -E 's/^([^ ]+) = undefined$/\1 = error "\1"/' file1
awk '$3=="undefined"{ $3="error \"" $1 "\"" } {print $0}' file1
두 번째 예의 경우 =를 기준으로 합니다.가치모두 대문자이거나 모두 숫자입니다. 또한 Magic이 아닌 모든 행을 그룹화합니다(삭제하려면 out[0]
명령문만 삭제).
awk -F'=' 'BEGIN{ # split regular expressions, using `x7F` as delimiter (or any char not in the regex)
n=split("^[A-Z]+$" "\x7F" "^[0-9]+$",rx,"\x7F")
}
{ for( i=1;i<=n;i++ ){
if( $2 ~ rx[i] ){
out[i]=out[i] sprintf( (out[i] ?", " :"") "%s", $2)
break
} }
if( i>n ) out[0]=out[0] $0 RS # non-matching lines
}
END{ printf out[0]
for( i=1;i<=n;i++ ){ print "Magic(" out[i] ")" }
}' file2
답변3
Perl은 강력한 텍스트 조작(검색, vi(1) 스타일의 정규식 대체)을 기반으로 구축된 (상당히 "일반적인") 프로그래밍 언어이기 때문에 Perl을 사용합니다. 하지만 많은 사람들은 내가 이단자라고 생각하고 Python을 사용할 것입니다. 둘 다 모든 Linux 배포판과 함께 배포되며 둘 다 적절한 Windows 구현을 갖추고 있습니다(Mac에서도 마찬가지라고 확신합니다). Python의 장점은 Fedora와 같은 관리 도구용 대부분의 GUI를 구축하는 데 사용할 수 있으므로 이미 설치되어 있어야 한다는 것입니다.
awk(1)
모두 sed(1)
강력한 도구이지만 일부는 전문화되어 있습니다.