Communities

Writing
Writing
Codidact Meta
Codidact Meta
The Great Outdoors
The Great Outdoors
Photography & Video
Photography & Video
Scientific Speculation
Scientific Speculation
Cooking
Cooking
Electrical Engineering
Electrical Engineering
Judaism
Judaism
Languages & Linguistics
Languages & Linguistics
Software Development
Software Development
Mathematics
Mathematics
Christianity
Christianity
Code Golf
Code Golf
Music
Music
Physics
Physics
Linux Systems
Linux Systems
Power Users
Power Users
Tabletop RPGs
Tabletop RPGs
Community Proposals
Community Proposals
tag:snake search within a tag
answers:0 unanswered questions
user:xxxx search by author id
score:0.5 posts with 0.5+ score
"snake oil" exact phrase
votes:4 posts with 4+ votes
created:<1w created < 1 week ago
post_type:xxxx type of post
Search help
Notifications
Mark all as read See all your notifications »
Q&A

Post History

75%
+4 −0
Q&A How to extract string from file, run filter, and replace in file with new value?

(Assuming your file names are portable, according to POSIX (https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap03.html#tag_03_282). If not, please read this for writing a more robust...

posted 6mo ago by alx‭  ·  edited 6mo ago by alx‭

Answer
#8: Post edited by user avatar alx‭ · 2023-11-25T23:27:36Z (6 months ago)
  • (Assuming your file names are portable, according to POSIX (<https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap03.html#tag_03_282>). If not, please read this for writing a more robust script: <https://linux.codidact.com/posts/288310/289999#answer-289999>.)
  • ```
  • find . -type f \
  • | grep '/chapter-[^/]*.xhtml$' \
  • | while read f; do
  • (
  • head -n11 <"$f";
  • sed -n '12p' <"$f" | titlecase;
  • tail -n+13 <"$f";
  • ) \
  • | sponge "$f";
  • done;
  • ```
  • - `find | grep` is for getting the file names.
  • - `while read` starts a subshell for each file name, where the inner commands are run.
  • - `() | sponge "$f"` will put everything printed by the `(...)` into the original file, atomically after all other commands have finished. sponge(1) is provided by the moreutils package.
  • - `head -n11` prints the first 11 lines pristine.
  • - `sed -n 12p` prints the 12th line pristine.
  • - `titlecase`: Your script, assuming it reads stdin, and writes to stdout.
  • - `tail -n+13` prints the remaining lines, starting at 13, pristine.
  • ---
  • Disclaimer: untested. If you provide some samples, I'll test it.
  • ---
  • If for some reason, you'd want to read a file only once, you could try writing a more complex filter using perl(1) (or maybe you manage to write it in sed(1)). That would remove the need for head(1) and tail(1).
  • ```sh
  • $ echo -e 'ASD
  • FOO BAR BAZ
  • QWE
  • RTY' \
  • | perl -p -e 's/(?<=[[:alpha:]])([[:upper:]])/\L\1/g if 2 .. 3';
  • ASD
  • Foo Bar Baz
  • Qwe
  • RTY
  • ```
  • (Assuming your file names are portable, according to POSIX (<https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap03.html#tag_03_282>). If not, please read this for writing a more robust script: <https://linux.codidact.com/posts/288310/289999#answer-289999>.)
  • ```
  • find . -type f \
  • | grep '/chapter-[^/]*.xhtml$' \
  • | while read f; do
  • (
  • head -n11 <"$f";
  • sed -n '12p' <"$f" | titlecase;
  • tail -n+13 <"$f";
  • ) \
  • | sponge "$f";
  • done;
  • ```
  • - `find | grep` is for getting the file names.
  • - `while read` starts a subshell for each file name, where the inner commands are run.
  • - `() | sponge "$f"` will put everything printed by the `(...)` into the original file, atomically after all other commands have finished. sponge(1) is provided by the moreutils package.
  • - `head -n11` prints the first 11 lines pristine.
  • - `sed -n 12p` prints the 12th line pristine.
  • - `titlecase`: Your script, assuming it reads stdin, and writes to stdout.
  • - `tail -n+13` prints the remaining lines, starting at 13, pristine.
  • ---
  • Disclaimer: untested. If you provide some samples, I'll test it.
  • ---
  • If for some reason, you'd want to read a file only once, you could try writing a more complex filter using perl(1) (or maybe you manage to write it in sed(1)). That would remove the need for head(1) and tail(1).
  • ```sh
  • $ printf 'ASD
  • FOO BAR BAZ
  • QWE
  • RTY\n' \
  • | perl -p -e 's/(?<=[[:alpha:]])([[:upper:]])/\L\1/g if 2 .. 3';
  • ASD
  • Foo Bar Baz
  • Qwe
  • RTY
  • ```
#7: Post edited by user avatar alx‭ · 2023-11-25T23:26:34Z (6 months ago)
  • (Assuming your file names are portable, according to POSIX (<https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap03.html#tag_03_282>). If not, please read this for writing a more robust script: <https://linux.codidact.com/posts/288310/289999#answer-289999>.)
  • ```
  • find . -type f \
  • | grep '/chapter-[^/]*.xhtml$' \
  • | while read f; do
  • (
  • head -n11 <"$f";
  • sed -n '12p' <"$f" | titlecase;
  • tail -n+13 <"$f";
  • ) \
  • | sponge "$f";
  • done;
  • ```
  • - `find | grep` is for getting the file names.
  • - `while read` starts a subshell for each file name, where the inner commands are run.
  • - `() | sponge "$f"` will put everything printed by the `(...)` into the original file, atomically after all other commands have finished. sponge(1) is provided by the moreutils package.
  • - `head -n11` prints the first 11 lines pristine.
  • - `sed -n 12p` prints the 12th line pristine.
  • - `titlecase`: Your script, assuming it reads stdin, and writes to stdout.
  • - `tail -n+13` prints the remaining lines, starting at 13, pristine.
  • ---
  • Disclaimer: untested. If you provide some samples, I'll test it.
  • ---
  • If for some reason, you'd want to read a file only once, you could try writing a more complex filter using perl(1) (or maybe you manage to write it in sed(1)). That would remove the need for head(1) and tail(1).
  • ```sh
  • $ echo -e 'ASD
  • FOO BAR BAZ
  • QWE' \
  • | perl -p -e 's/(?<=[[:alpha:]])([[:upper:]])/\L\1/g if 2 .. 2';
  • ASD
  • Foo Bar Baz
  • QWE
  • ```
  • (Assuming your file names are portable, according to POSIX (<https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap03.html#tag_03_282>). If not, please read this for writing a more robust script: <https://linux.codidact.com/posts/288310/289999#answer-289999>.)
  • ```
  • find . -type f \
  • | grep '/chapter-[^/]*.xhtml$' \
  • | while read f; do
  • (
  • head -n11 <"$f";
  • sed -n '12p' <"$f" | titlecase;
  • tail -n+13 <"$f";
  • ) \
  • | sponge "$f";
  • done;
  • ```
  • - `find | grep` is for getting the file names.
  • - `while read` starts a subshell for each file name, where the inner commands are run.
  • - `() | sponge "$f"` will put everything printed by the `(...)` into the original file, atomically after all other commands have finished. sponge(1) is provided by the moreutils package.
  • - `head -n11` prints the first 11 lines pristine.
  • - `sed -n 12p` prints the 12th line pristine.
  • - `titlecase`: Your script, assuming it reads stdin, and writes to stdout.
  • - `tail -n+13` prints the remaining lines, starting at 13, pristine.
  • ---
  • Disclaimer: untested. If you provide some samples, I'll test it.
  • ---
  • If for some reason, you'd want to read a file only once, you could try writing a more complex filter using perl(1) (or maybe you manage to write it in sed(1)). That would remove the need for head(1) and tail(1).
  • ```sh
  • $ echo -e 'ASD
  • FOO BAR BAZ
  • QWE\nRTY' \
  • | perl -p -e 's/(?<=[[:alpha:]])([[:upper:]])/\L\1/g if 2 .. 3';
  • ASD
  • Foo Bar Baz
  • Qwe
  • RTY
  • ```
#6: Post edited by user avatar alx‭ · 2023-11-25T23:25:27Z (6 months ago)
  • (Assuming your file names are portable, according to POSIX (<https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap03.html#tag_03_282>). If not, please read this for writing a more robust script: <https://linux.codidact.com/posts/288310/289999#answer-289999>.)
  • ```
  • find . -type f \
  • | grep '/chapter-[^/]*.xhtml$' \
  • | while read f; do
  • (
  • head -n11 <"$f";
  • sed -n '12p' <"$f" | titlecase;
  • tail -n+13 <"$f";
  • ) \
  • | sponge "$f";
  • done;
  • ```
  • - `find | grep` is for getting the file names.
  • - `while read` starts a subshell for each file name, where the inner commands are run.
  • - `() | sponge "$f"` will put everything printed by the `(...)` into the original file, atomically after all other commands have finished. sponge(1) is provided by the moreutils package.
  • - `head -n11` prints the first 11 lines pristine.
  • - `sed -n 12p` prints the 12th line pristine.
  • - `titlecase`: Your script, assuming it reads stdin, and writes to stdout.
  • - `tail -n+13` prints the remaining lines, starting at 13, pristine.
  • ---
  • Disclaimer: untested. If you provide some samples, I'll test it.
  • ---
  • If for some reason, you'd want to read a file only once, you could try writing a more complex filter using perl(1) (or maybe you manage to write it in sed(1)). That would remove the need for head(1) and tail(1).
  • ```sh
  • $ echo -e 'ASD\nFOO BAR BAZ\nQWE' \
  • | perl -p -e 's/(?<=[[:alpha:]])([[:upper:]])/\L\1/g if 2 .. 2'
  • ASD
  • Foo Bar Baz
  • QWE
  • ```
  • (Assuming your file names are portable, according to POSIX (<https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap03.html#tag_03_282>). If not, please read this for writing a more robust script: <https://linux.codidact.com/posts/288310/289999#answer-289999>.)
  • ```
  • find . -type f \
  • | grep '/chapter-[^/]*.xhtml$' \
  • | while read f; do
  • (
  • head -n11 <"$f";
  • sed -n '12p' <"$f" | titlecase;
  • tail -n+13 <"$f";
  • ) \
  • | sponge "$f";
  • done;
  • ```
  • - `find | grep` is for getting the file names.
  • - `while read` starts a subshell for each file name, where the inner commands are run.
  • - `() | sponge "$f"` will put everything printed by the `(...)` into the original file, atomically after all other commands have finished. sponge(1) is provided by the moreutils package.
  • - `head -n11` prints the first 11 lines pristine.
  • - `sed -n 12p` prints the 12th line pristine.
  • - `titlecase`: Your script, assuming it reads stdin, and writes to stdout.
  • - `tail -n+13` prints the remaining lines, starting at 13, pristine.
  • ---
  • Disclaimer: untested. If you provide some samples, I'll test it.
  • ---
  • If for some reason, you'd want to read a file only once, you could try writing a more complex filter using perl(1) (or maybe you manage to write it in sed(1)). That would remove the need for head(1) and tail(1).
  • ```sh
  • $ echo -e 'ASD\nFOO BAR BAZ\nQWE' \
  • | perl -p -e 's/(?<=[[:alpha:]])([[:upper:]])/\L\1/g if 2 .. 2';
  • ASD
  • Foo Bar Baz
  • QWE
  • ```
#5: Post edited by user avatar alx‭ · 2023-11-25T23:25:07Z (6 months ago)
  • (Assuming your file names are portable, according to POSIX (<https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap03.html#tag_03_282>). If not, please read this for writing a more robust script: <https://linux.codidact.com/posts/288310/289999#answer-289999>.)
  • ```
  • find . -type f \
  • | grep '/chapter-[^/]*.xhtml$' \
  • | while read f; do
  • (
  • head -n11 <"$f";
  • sed -n '12p' <"$f" | titlecase;
  • tail -n+13 <"$f";
  • ) \
  • | sponge "$f";
  • done;
  • ```
  • - `find | grep` is for getting the file names.
  • - `while read` starts a subshell for each file name, where the inner commands are run.
  • - `() | sponge "$f"` will put everything printed by the `(...)` into the original file, atomically after all other commands have finished. sponge(1) is provided by the moreutils package.
  • - `head -n11` prints the first 11 lines pristine.
  • - `sed -n 12p` prints the 12th line pristine.
  • - `titlecase`: Your script, assuming it reads stdin, and writes to stdout.
  • - `tail -n+13` prints the remaining lines, starting at 13, pristine.
  • ---
  • Disclaimer: untested. If you provide some samples, I'll test it.
  • ---
  • If for some reason, you'd want to read a file only once, you could try writing a more complex filter using perl(1) (or maybe you manage to write it in sed(1)). That would remove the need for head(1) and tail(1).
  • ```sh
  • $ echo -e 'ASD
  • FOO BAR BAZ
  • QWE' | perl -p -e 's/(?<=[[:alpha:]])([[:upper:]])/\L\1/g if 2 .. 2'
  • ASD
  • Foo Bar Baz
  • QWE
  • ```
  • (Assuming your file names are portable, according to POSIX (<https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap03.html#tag_03_282>). If not, please read this for writing a more robust script: <https://linux.codidact.com/posts/288310/289999#answer-289999>.)
  • ```
  • find . -type f \
  • | grep '/chapter-[^/]*.xhtml$' \
  • | while read f; do
  • (
  • head -n11 <"$f";
  • sed -n '12p' <"$f" | titlecase;
  • tail -n+13 <"$f";
  • ) \
  • | sponge "$f";
  • done;
  • ```
  • - `find | grep` is for getting the file names.
  • - `while read` starts a subshell for each file name, where the inner commands are run.
  • - `() | sponge "$f"` will put everything printed by the `(...)` into the original file, atomically after all other commands have finished. sponge(1) is provided by the moreutils package.
  • - `head -n11` prints the first 11 lines pristine.
  • - `sed -n 12p` prints the 12th line pristine.
  • - `titlecase`: Your script, assuming it reads stdin, and writes to stdout.
  • - `tail -n+13` prints the remaining lines, starting at 13, pristine.
  • ---
  • Disclaimer: untested. If you provide some samples, I'll test it.
  • ---
  • If for some reason, you'd want to read a file only once, you could try writing a more complex filter using perl(1) (or maybe you manage to write it in sed(1)). That would remove the need for head(1) and tail(1).
  • ```sh
  • $ echo -e 'ASD
  • FOO BAR BAZ
  • QWE' \
  • | perl -p -e 's/(?<=[[:alpha:]])([[:upper:]])/\L\1/g if 2 .. 2'
  • ASD
  • Foo Bar Baz
  • QWE
  • ```
#4: Post edited by user avatar alx‭ · 2023-11-25T23:24:15Z (6 months ago)
  • (Assuming your file names are portable, according to POSIX (<https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap03.html#tag_03_282>). If not, please read this for writing a more robust script: <https://linux.codidact.com/posts/288310/289999#answer-289999>.)
  • ```
  • find . -type f \
  • | grep '/chapter-[^/]*.xhtml$' \
  • | while read f; do
  • (
  • head -n11 <"$f";
  • sed -n '12p' <"$f" | titlecase;
  • tail -n+13 <"$f";
  • ) \
  • | sponge "$f";
  • done;
  • ```
  • - `find | grep` is for getting the file names.
  • - `while read` starts a subshell for each file name, where the inner commands are run.
  • - `() | sponge "$f"` will put everything printed by the `(...)` into the original file, atomically after all other commands have finished. sponge(1) is provided by the moreutils package.
  • - `head -n11` prints the first 11 lines pristine.
  • - `sed -n 12p` prints the 12th line pristine.
  • - `titlecase`: Your script, assuming it reads stdin, and writes to stdout.
  • - `tail -n+13` prints the remaining lines, starting at 13, pristine.
  • ---
  • Disclaimer: untested. If you provide some samples, I'll test it.
  • (Assuming your file names are portable, according to POSIX (<https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap03.html#tag_03_282>). If not, please read this for writing a more robust script: <https://linux.codidact.com/posts/288310/289999#answer-289999>.)
  • ```
  • find . -type f \
  • | grep '/chapter-[^/]*.xhtml$' \
  • | while read f; do
  • (
  • head -n11 <"$f";
  • sed -n '12p' <"$f" | titlecase;
  • tail -n+13 <"$f";
  • ) \
  • | sponge "$f";
  • done;
  • ```
  • - `find | grep` is for getting the file names.
  • - `while read` starts a subshell for each file name, where the inner commands are run.
  • - `() | sponge "$f"` will put everything printed by the `(...)` into the original file, atomically after all other commands have finished. sponge(1) is provided by the moreutils package.
  • - `head -n11` prints the first 11 lines pristine.
  • - `sed -n 12p` prints the 12th line pristine.
  • - `titlecase`: Your script, assuming it reads stdin, and writes to stdout.
  • - `tail -n+13` prints the remaining lines, starting at 13, pristine.
  • ---
  • Disclaimer: untested. If you provide some samples, I'll test it.
  • ---
  • If for some reason, you'd want to read a file only once, you could try writing a more complex filter using perl(1) (or maybe you manage to write it in sed(1)). That would remove the need for head(1) and tail(1).
  • ```sh
  • $ echo -e 'ASD\nFOO BAR BAZ\nQWE' | perl -p -e 's/(?<=[[:alpha:]])([[:upper:]])/\L\1/g if 2 .. 2'
  • ASD
  • Foo Bar Baz
  • QWE
  • ```
#3: Post edited by user avatar alx‭ · 2023-11-25T13:53:15Z (6 months ago)
  • (Assuming your file names are portable, according to POSIX (<https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap03.html#tag_03_282>). If not, please read this for writing a more robust script: <https://linux.codidact.com/posts/288310>.)
  • ```
  • find . -type f \
  • | grep '/chapter-[^/]*.xhtml$' \
  • | while read f; do
  • (
  • head -n11 <"$f";
  • sed -n '12p' <"$f" | titlecase;
  • tail -n+13 <"$f";
  • ) \
  • | sponge "$f";
  • done;
  • ```
  • - `find | grep` is for getting the file names.
  • - `while read` starts a subshell for each file name, where the inner commands are run.
  • - `() | sponge "$f"` will put everything printed by the `(...)` into the original file, atomically after all other commands have finished. sponge(1) is provided by the moreutils package.
  • - `head -n11` prints the first 11 lines pristine.
  • - `sed -n 12p` prints the 12th line pristine.
  • - `titlecase`: Your script, assuming it reads stdin, and writes to stdout.
  • - `tail -n+13` prints the remaining lines, starting at 13, pristine.
  • ---
  • Disclaimer: untested. If you provide some samples, I'll test it.
  • (Assuming your file names are portable, according to POSIX (<https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap03.html#tag_03_282>). If not, please read this for writing a more robust script: <https://linux.codidact.com/posts/288310/289999#answer-289999>.)
  • ```
  • find . -type f \
  • | grep '/chapter-[^/]*.xhtml$' \
  • | while read f; do
  • (
  • head -n11 <"$f";
  • sed -n '12p' <"$f" | titlecase;
  • tail -n+13 <"$f";
  • ) \
  • | sponge "$f";
  • done;
  • ```
  • - `find | grep` is for getting the file names.
  • - `while read` starts a subshell for each file name, where the inner commands are run.
  • - `() | sponge "$f"` will put everything printed by the `(...)` into the original file, atomically after all other commands have finished. sponge(1) is provided by the moreutils package.
  • - `head -n11` prints the first 11 lines pristine.
  • - `sed -n 12p` prints the 12th line pristine.
  • - `titlecase`: Your script, assuming it reads stdin, and writes to stdout.
  • - `tail -n+13` prints the remaining lines, starting at 13, pristine.
  • ---
  • Disclaimer: untested. If you provide some samples, I'll test it.
#2: Post edited by user avatar alx‭ · 2023-11-25T13:52:39Z (6 months ago)
  • (Assuming your file names are portable, according to POSIX (<https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap03.html#tag_03_282>). If not, please read this for writing a more robust script: <https://linux.codidact.com/posts/288310>.)
  • ```
  • find . -type f \
  • | grep '/chapter-[^/]*.xhtml$' \
  • | while read f; do
  • (
  • head -n11 <"$f";
  • sed -n '12p' <"$f" | titlecase;
  • tail -n+13 <"$f";
  • ) \
  • | sponge "$f";
  • done;
  • ```
  • - `find | grep` is for getting the file names.
  • - `while read` starts a subshell for each file name, where the inner commands are run.
  • - `() | sponge "$f"` will put everything printed by the `(...)` into the original file, atomically after all other commands have finished. sponge(1) is provided by the moreutils package.
  • - `head -n11` prints the first 11 lines pristine.
  • - `sed -n 12p` prints the 12th line pristine.
  • - `titlecase`: Your script, assuming it reads stdin, and writes to stdout.
  • - `tail -n+13` prints the remaining lines, starting at 13, pristine.
  • (Assuming your file names are portable, according to POSIX (<https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap03.html#tag_03_282>). If not, please read this for writing a more robust script: <https://linux.codidact.com/posts/288310>.)
  • ```
  • find . -type f \
  • | grep '/chapter-[^/]*.xhtml$' \
  • | while read f; do
  • (
  • head -n11 <"$f";
  • sed -n '12p' <"$f" | titlecase;
  • tail -n+13 <"$f";
  • ) \
  • | sponge "$f";
  • done;
  • ```
  • - `find | grep` is for getting the file names.
  • - `while read` starts a subshell for each file name, where the inner commands are run.
  • - `() | sponge "$f"` will put everything printed by the `(...)` into the original file, atomically after all other commands have finished. sponge(1) is provided by the moreutils package.
  • - `head -n11` prints the first 11 lines pristine.
  • - `sed -n 12p` prints the 12th line pristine.
  • - `titlecase`: Your script, assuming it reads stdin, and writes to stdout.
  • - `tail -n+13` prints the remaining lines, starting at 13, pristine.
  • ---
  • Disclaimer: untested. If you provide some samples, I'll test it.
#1: Initial revision by user avatar alx‭ · 2023-11-25T13:50:59Z (6 months ago)
(Assuming your file names are portable, according to POSIX (<https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap03.html#tag_03_282>).  If not, please read this for writing a more robust script: <https://linux.codidact.com/posts/288310>.)

```
find . -type f \
| grep '/chapter-[^/]*.xhtml$' \
| while read f; do
        (
                head -n11 <"$f";
                sed -n '12p' <"$f" | titlecase;
                tail -n+13 <"$f";
        ) \
        | sponge "$f";
done;
```

-  `find | grep` is for getting the file names.

-  `while read` starts a subshell for each file name, where the inner commands are run.

-  `() | sponge "$f"` will put everything printed by the `(...)` into the original file, atomically after all other commands have finished.  sponge(1) is provided by the moreutils package.

-  `head -n11` prints the first 11 lines pristine.
-  `sed -n 12p` prints the 12th line pristine.
-  `titlecase`: Your script, assuming it reads stdin, and writes to stdout.
-  `tail -n+13` prints the remaining lines, starting at 13, pristine.