텍스트 파일이 몇 개 있는데 다음 작업을 수행하고 싶습니다.이동하다파일의 이전 또는 다음 줄의 모든 줄(파일의 시작 또는 끝 줄은 원래 위치에 남습니다). 작동하는 코드가 몇 가지 있지만 지저분해 보이고 모든 극단적인 경우를 다루었다고 생각하지 않습니다. 따라서 이 작업을 더 잘 수행할 수 있는 도구나 패러다임이 있는지 궁금합니다(예: 이해하기 쉽게 만들어줌) 코드(6개월 이내의 다른 독자나 나에게), 디버깅이 쉽고, 유지 관리가 더 쉽다는 것은 실제로 중요하지 않습니다.
move_up() {
# fetch line with head -<line number> | tail -1
# insert that one line higher
# delete the old line
sed -i -e "$((line_number-1))i$(head -$line_number $file | tail -1)" -e "${line_number}d" "$file"
}
move_down() {
file_length=$(wc -l < "$file")
if [[ "$line_number" -ge $((file_length - 1)) ]]; then
# sed can't insert past the end of the file, so append the line
# then delete the old line
echo $(head -$line_number "$file" | tail -1) >> "$file"
sed -i "${line_number}d" "$file"
else
# get the line, and insert it after the next line, and delete the original
sed -i -e "$((line_number+2))i$(head -$line_number $file | tail -1)" -e "${line_number}d" "$file"
fi
}
이러한 함수 내부 또는 외부의 입력에 대해 오류 검사를 수행할 수 있지만 잘못된 입력(예: 정수가 아닌 파일, 파일 길이보다 큰 줄 번호)이 올바르게 처리되면 보너스 포인트가 될 것입니다.
최신 Debian/Ubuntu 시스템의 Bash 스크립트에서 실행하고 싶습니다. 항상 루트 액세스 권한이 있는 것은 아니지만 "표준" 도구(공유 네트워크 서버 등)를 설치할 것으로 기대할 수 있습니다.가능한요청의 정당성을 입증할 수 있는 경우 추가 도구 설치를 요청할 수 있습니다(외부 종속성이 적을수록 좋습니다).
예:
$ cat b
1
2
3
4
$ file=b line_number=3 move_up
$ cat b
1
3
2
4
$ file=b line_number=3 move_down
$ cat b
1
3
4
2
$
답변1
~처럼아처마르제안된 대로 다음을 사용하여 이를 스크립팅할 수 있습니다 ed
.
printf %s\\n ${linenr}m${addr} w q | ed -s infile
즉
linenr # is the line number
m # command that moves the line
addr=$(( linenr + 1 )) # if you move the line down
addr=$(( linenr - 2 )) # if you move the line up
w # write changes to file
q # quit editor
예를 들어 줄 번호를 이동합니다. 21
팀:
printf %s\\n 21m19 w q | ed -s infile
줄 번호를 21
한 줄 아래로 이동합니다.
printf %s\\n 21m22 w q | ed -s infile
그러나 특정 행을 한 행 위나 아래로 이동하기만 하면 되므로 실제로 두 개의 연속 행을 교환하고 싶다고 말할 수도 있습니다. 만나다 sed
:
sed -i -n 'addr{h;n;G};p' infile
즉
addr=${linenr} # if you move the line down
addr=$(( linenr - 1 )) # if you move the line up
h # replace content of the hold buffer with a copy of the pattern space
n # read a new line replacing the current line in the pattern space
G # append the content of the hold buffer to the pattern space
p # print the entire pattern space
예를 들어 줄 번호를 이동합니다. 21
팀:
sed -i -n '20{h;n;G};p' infile
줄 번호를 21
한 줄 아래로 이동합니다.
sed -i -n '21{h;n;G};p' infile
gnu sed
위의 구문을 사용했습니다 . 이식성이 문제인 경우:
sed -n 'addr{
h
n
G
}
p' infile
그 외에 일반적인 검사는 다음과 같습니다. 파일이 존재하고 쓰기 가능 합니다 file_length > 2
.line_no. > 1
line_no. < file_length
답변2
vi에는 move라는 명령이 있습니다m
텍스트 모드에서 vi를 사용할 수 있습니다: ex
$line_number=7
$line_up=$(($line_number + 1 ))
(echo ${line_number}m${line_up} ; echo wq ) | ex foo
어디
foo
당신 파일이에요
답변3
vims 사용하기(sed 모드의 vim):https://github.com/MilesCranmer/vim-stream
당신은 할 수 있습니다:
cat file.txt | vims "$NUMBERm.-1"
행을 한 위치 아래로 이동합니다.