텍스트 파일의 한 줄을 한 줄 위나 아래로 이동하는 방법은 무엇입니까?

텍스트 파일의 한 줄을 한 줄 위나 아래로 이동하는 방법은 무엇입니까?

텍스트 파일이 몇 개 있는데 다음 작업을 수행하고 싶습니다.이동하다파일의 이전 또는 다음 줄의 모든 줄(파일의 시작 또는 끝 줄은 원래 위치에 남습니다). 작동하는 코드가 몇 가지 있지만 지저분해 보이고 모든 극단적인 경우를 다루었다고 생각하지 않습니다. 따라서 이 작업을 더 잘 수행할 수 있는 도구나 패러다임이 있는지 궁금합니다(예: 이해하기 쉽게 만들어줌) 코드(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. > 1line_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"

행을 한 위치 아래로 이동합니다.

관련 정보