используя sed и awk для копирования имени файла в файл - PullRequest
0 голосов
/ 10 мая 2018

Я недавно добавил вопрос здесь о том, как использовать sed и awk, чтобы взять текстовую строку в файле и использовать ее для именования файла. Сейчас я пытаюсь выяснить, как наоборот - используйте имя файла и вставьте этот текст в файл в указанной точке.

Используя тот же текстовый пример, скажем, этот файл называется test1.Rnw :

\begin{question}


A business incurs the following costs per unit: Labor  \$125/unit; Materials \$45/unit and rent  \$250,000/month. If the firm produces 1,000,000 units a month, the total variable costs equal
\begin{answerlist} 
\item \$125Million

\item \$45Million

\item \$1Million

\item \$170Million


\end{answerlist}
\end{question}

\begin{solution}
\begin{answerlist}
\item F. 
\item F. 
\item F. 
\item F. 
\end{answerlist}
\end{solution}

\exname{target}
\extype{schoice}
\exsolution{0001}
\exshuffle{TRUE}

Теперь я хочу взять имя файла test1.Rnw и вставить этот текст в этот файл в месте \ exname {target}, заменив текст target. Предпочтительно, я мог бы просто вставить test1 и , а не расширение .Rnw здесь.

Я надеялся, что смогу использовать свой предыдущий вопрос (и очень хороший ответ), чтобы найти решение, но я застрял.

=======

Ответы [ 2 ]

0 голосов
/ 10 мая 2018

Учитывая target в \exname{target} - это то, что вас интересует:

1) Чтобы назвать файл на основе значения target:

awk -F'[{}]' 'NR==FNR{if ($1=="\\exname") fname=$2; next} {print > fname}' file file

2) Заменить target текущим именем файла:

awk -F'[{}]' '$1=="\\exname"{ $0 = $1 "{" FILENAME "}" } 1' file

Вам НЕ НУЖНА оболочка для работы с несколькими файлами, но в этом случае у нее простой, привлекательный согласованный синтаксис:

for file in *; do
   awk as above but replace `file` with `"$file"`
done

и если вы хотите заменить исходный файл выводом команды awk:

for file in *; do
   awk -F'[{}]' 'NR==FNR{if ($1=="\\exname") fname=$2; next} {print > fname}' "$file" "$file" &&
   rm -f "$file"
done

for file in *; do
   awk -F'[{}]' '$1=="\\exname"{ $0 = $1 "{" FILENAME "}" } 1' "$file" > tmp &&
   mv tmp "$file"
done
0 голосов
/ 10 мая 2018

У вас есть разные способы выполнения работы, я бы порекомендовал использовать sed, так как вы хотите заменить какой-то шаблон в файле.

ВХОД:

$ cat test1.rnw

\begin{question}


A business incurs the following costs per unit: Labor  \$125/unit; Materials \$45/unit and rent  \$250,000/month. If the firm produces 1,000,000 units a month, the total variable costs equal
\begin{answerlist} 
\item \$125Million

\item \$45Million

\item \$1Million

\item \$170Million


\end{answerlist}
\end{question}

\begin{solution}
\begin{answerlist}
\item F. 
\item F. 
\item F. 
\item F. 
\end{answerlist}
\end{solution}

\exname{target}
\extype{schoice}
\exsolution{0001}
\exshuffle{TRUE}

Команда:

FILENAME=`basename test1.rnw .rnw`; sed 's/^\\exname{target}/\\exname{'"$FILENAME"'}/' test1.rnw

Пояснения:

  • basename используется с именем файла и расширением, чтобы удалить его из имени файла, результат сохраняется в переменной с именем FILENAME.
  • Вы используете find and replace функцию sed и заменяете ^\\exname{target} (строки, начинающиеся с \exname{target} на \exname{, сопровождаемые содержимым переменной FILENAME и заканчивающиеся }

ВЫВОД:

\begin{question}


A business incurs the following costs per unit: Labor  \$125/unit; Materials \$45/unit and rent  \$250,000/month. If the firm produces 1,000,000 units a month, the total variable costs equal
\begin{answerlist} 
\item \$125Million

\item \$45Million

\item \$1Million

\item \$170Million


\end{answerlist}
\end{question}

\begin{solution}
\begin{answerlist}
\item F. 
\item F. 
\item F. 
\item F. 
\end{answerlist}
\end{solution}

\exname{test1}
\extype{schoice}
\exsolution{0001}
\exshuffle{TRUE}

TODO:

  • перенаправить стандартный вывод в файл, чтобы сохранить результат
  • или используйте -i или -i.bak для внесения изменений на месте (СДЕЛАЙТЕ РЕЗЕРВНОЕ КОПИРОВАНИЕ ПЕРЕД)

DOC:

https://www.gnu.org/software/sed/manual/sed.html

Если вы любитель awk, вы также можете использовать следующую команду для достижения того же результата:

awk '/^\\exname/{noext=FILENAME;sub(/\..*$/,"",noext);print "\\exname{"noext"}";next}1{print}' test1.rnw

Пояснения:

  • 1{print} напечатает каждую строку
  • /^\\exname/{noext=FILENAME;sub(/\..*$/,"",noext);print "\\exname{"noext"}";next} для строк, начинающихся с \exname, вы получаете доступ к FILENAME и удаляете расширение с помощью noext=FILENAME;sub(/\..*$/,"",noext), затем вы печатаете строку с помощью print "\\exname{"noext"}" и переходите к строке next, чтобы избежать двойной печати.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...