모든 사람--
나는 이것에 대해 조금 혼란스러워합니다. csplit을 사용하여 여러 입력 파일을 가져와 동일한 패턴에 따라 분할하는 bash 스크립트를 작성하려고 합니다. (문맥상: \question 명령으로 구분된 질문이 포함된 TeX 파일이 여러 개 있습니다. 각 질문을 자체 파일로 추출하고 싶습니다.)
지금까지 내 코드는 다음과 같습니다.
#!/bin/bash
# This script uses csplit to run through an input TeX file (or list of TeX files) to separate out all the questions into their own files.
# This line is for the user to input the name of the file they need questions split from.
read -ep "Type the directory and/or name of the file needed to split. If there is more than one file, enter the files separated by a space. " files
read -ep "Type the directory where you would like to save the split files: " save
read -ep "What unit do these questions belong to?" unit
# This is a check for the user to confirm the file list, and proceed if true:
echo "The file(s) being split is/are $files. Please confirm that you wish to split this file, or cancel."
select ynf in "Yes" "No"; do
case $ynf in
No ) exit;;
Yes ) echo "The split files will be saved to $save. Please confirm that you wish to save the files here."
select ynd in "Yes" "No"; do
case $ynd in
Yes )
# This line will create a loop to conduct the script over all the files in the list.
for i in ${files[@]}
do
# Mass re-naming is formatted to give "guestion###.tex' to enable processing a large number of questions quickly.
# csplit is the utility used here; run "man csplit" to learn more of its functionality.
# the structure is "csplit [name of file] [output options] [search filter] [separator(s)].
# this script calls csplit, will accept the name of the file in the argument, searches the files for calls of "question", splits the file everywhere it finds a line with "question", and renames it according to the scheme [prefix]#[suffix] (the %03d in the suffix-format is what increments the numbering automatically).
# the '\\question' allows searching for \question, which eliminates the split for \end{questions}; eliminating the \begin{questions} split has not yet been understood.
csplit $i --prefix=$save'/'$unit'q' --suffix-format='%03d.tex' /'\\question'/ '{*}'
done; exit;;
No ) exit;;
esac
done
esac
done
return
입력 파일에 대해 예상한 대로 반복되는 것을 확인할 수 있습니다. 그러나 내가 알아차린 동작은 예상대로 첫 번째 파일을 "q1.tex q2.tex q3.tex"로 분할하고 목록의 다음 파일로 이동하면 문제를 분할하고 이전 파일을 덮어쓴다는 것입니다. 세 번째 파일은 두 번째 파일의 분할을 덮어씁니다. 내가 원하는 것은 File1에 3개의 문제가 있는 경우 다음과 같이 출력되는 것입니다.
q1.tex
q2.tex
q3.tex
그런 다음 File2에 4개의 문제가 있는 경우 계속해서 다음과 같이 증가합니다.
q4.tex
q5.tex
q6.tex
q7.tex
csplit이 이 루프에서 완료된 숫자를 감지하고 적절하게 증가시키는 방법이 있습니까?
모두가 제공할 수 있는 도움에 감사드립니다!
답변1
이 csplit
명령은 컨텍스트를 저장하지 않으며 저장하지도 않으므로 항상 1부터 계산을 시작합니다. 이 문제를 해결할 방법은 없지만 접두사 문자열에 삽입한 개수 값을 유지할 수 있습니다.
또는 교체해 보세요.
read -ep "Type the directory and/or name of the file needed to split. If there is more than one file, enter the files separated by a space. " files
...
for i in ${files[@]}
do
csplit $i --prefix=$save'/'$unit'q' --suffix-format='%03d.tex' /'\\question'/ '{*}'
done
그리고
read -a files -ep 'Type the directory and/or name of the file needed to split. If there is more than one file, enter the files separated by a space. '
...
cat "${files[@]}" | csplit - --prefix="$save/${unit}q" --suffix-format='%03d.tex' '/\\question/' '{*}'
이는 실제로 파일 인수만 cat {file} | ...
사용 하여 사용해야 하는 비교적 드문 경우 중 하나입니다( 또는csplit
-
표준 입력).
루프에서 read
배열 변수를 (올바르게) 사용하려고 하기 때문에 배열 변수를 사용하도록 작업을 변경했습니다 .for ... do csplit ...
궁극적으로 어떤 결정을 내리든 모든 변수, 특히 배열 목록(예: "${files[@]}"
.
답변2
Awk를 사용하면 다음을 실행할 수 있습니다.
awk '/\\question/ {i++} ; {print > "q" i ".tex"}' exam*.tex
out-dir(d) 및 topic(t)를 정의하고 번호 길이를 제어하려면 다음을 수행하십시오.
awk '/\\question/ {f=sprintf("%s/%s-q%03d.tex", d, t, i++)} {print>f}' d=d1 t=t1 ex*
TeX preambulo를 건너뛰려면 "f"를 정의할 때 "인쇄"할 수 있습니다.
awk '/\\question/ {f=sprintf("%s/%s-q%03d.tex", d, t, ++i)}
f {print>f}' d=d1 t=t1 ex*
답변3
이 스크립트를 사용할 수 있습니다
grep -o -P '(parameter).*(parameter)' your_teX_file.teX > questions.txt
모든 질문이 포함된 파일을 받게 되며 questions.txt
이를 분할할 수 있습니다.
split -l 1 questions.txt