How to browse multiple files like a single file

Asked 2 years ago, Updated 2 years ago, 59 views

$ls
hoge.text fuga.text piyo.text all.text
$ cathoge.
hoge
$ cat fuga.text
fuga
$ catpiyo.text
piyo
$ cat all.text
hoge
fuga
piyo
$ echo hoge>>hoge.text
$ cat all.text
hoge
hoge
fuga
piyo

Is this possible?

linux bash

2022-09-30 20:59

2 Answers

Yes, well, it's not impossible.However, I don't know if you'll be satisfied with the method described below.

The Linux operating system provides an API to selectively detect events that occur in the file system, called inotify, but try using it.

First, install inotify-related packages.For Ubuntu Linux, inotify-tools corresponds.

$sudo apt-get install notify-tools

For example, $HOME/tmp contains the file.

$cd$HOME/tmp
$ ls
fuga.text hoge.text piyo.text

Then run the following shell script:

update.sh

#!/bin/bash

target_dir = $HOME/tmp
files=(fuga.text hoge.textpiyo.text)
all = all.text

while notifywait-qqq-em modify@"$all""$target_dir";
do
  (cd "$target_dir" & cat "${files[@]}" > "$all")
done

$./update.sh&

Now let's actually change the file.

$cd$HOME/tmp
$ echo hoge>>hoge.text
$ cat all.text
fuga
hoge
hoge
piyo

The inotifywait command in the script waits for files in the $HOME/tmp directory to change.except for $HOME/tmp/all.text (@"$all").

$HOME/tmp Only the above files must exist in the directory.If there are other files, you will only need to specify the target file in the inotifywait command, but see inotifywait(1) for specific instructions.


2022-09-30 20:59

As an example of the question, only the cat command uses the file.
If you assume that one process at a time reads from the beginning to the end of the file, you can do so by letting them read the output of another process.
(I think the only way to make them behave as normal files without any assumptions is to create a file system that can create files with multiple files as backend using fuse etc.)

How to use a named pipe

First, create a named pipe file.

mkfifo all.txt

It then starts the process of concatenating and outputting files in the background.I will use cat this time.

cathoge.txt fuga.txt piyo.txt>all.txt&

If you read all.txt in this state, you will receive it from the above output process.
(nl is used for the reader's command after because it is confusing)

nl all.txt
# output below
     1 hoge
     2 fuga
     3piyo

If you read it to the end, the output process will end, so if you try to read it again, you will stop waiting for input to all.txt.
For example, if you try to repeat the output process as shown below, you will be able to read it over and over again.

while true; do cathoge.txt fuga.txt piyo.txt>all.txt;done&

How to use Bash process replacement

Bash has a function that automatically does the same thing as using a named pipe.
However, this method does not allow you to specify a filename, so you cannot use it if it must be all.txt.

In the Bash command line, the notation <(command) is replaced by the filename.

ls<(echo hello)
# Output in your environment: /dev/fd/63
# It's like you're using a file descriptor.
# In some environments, they use named pipes.

This file is provided by bash and is valid only if you read the main process (ls in the example above) that was performed in the command line.
The output of the command specified in <() is connected.
As an example of a question, you can do it as follows:

nl<(cathoge.txt fuga.txt piyo.txt)
# below output
     1 hoge
     2 fuga
     3piyo


2022-09-30 20:59

If you have any answers or tips


© 2024 OneMinuteCode. All rights reserved.